Pseudo-Elements and Replaced Elements in CSS
Pseudo-elements like ::before and ::after cannot be applied to replaced elements, such as <img>, <input>, <textarea>, <video>, or <iframe>. Replaced elements have intrinsic content defined by the browser or an external source, and pseudo-elements can only insert generated content into non-replaced elements.
Replaced elements have content that is not part of the HTML DOM structure (e.g., the image file itself).
Pseudo-elements like ::before and ::after only work on elements that can contain text or other non-replaced content.
Applying pseudo-elements to replaced elements will not render any visible output.
For decorative effects on replaced elements, consider wrapping them in a <div> or <span> and applying pseudo-elements to the wrapper.
In this example, the ::before pseudo-element is applied to the wrapper <div> around the image, allowing you to add decorative overlays or effects without directly targeting the <img> element.
Do not apply ::before or ::after directly to replaced elements; it will not work.
Use a wrapper element if you need pseudo-element-based decorations or overlays.
Style the pseudo-elements with position, z-index, and other visual properties to achieve the desired effect.
Test across browsers, as rendering behavior may differ slightly for replaced elements.
I tried to add a ::before pseudo-element to an <img> tag to show a badge icon, but nothing appears — what’s going on?
If I set content: '★' on img::after in CSS, will it show up next to the image? Why or why not?
How would you verify whether a pseudo-element is being applied to an <img> element using browser dev tools?
Our design team wants a decorative border around product images using ::before, but it’s not rendering — how do you debug this and what’s your workaround?
A teammate added a ::after element to an <img> to display a 'New' label, but it’s invisible in Chrome — what’s the root cause and how do you fix it without changing the HTML?
Why does this CSS rule work on a <div> but not on an <img>, even though both have the same class? Walk me through your debugging process.
We’re building a responsive image gallery with overlay badges — since pseudo-elements don’t work on <img>, how would you design a scalable, accessible solution that doesn’t bloat the DOM?
In a legacy component library, we have hundreds of images styled with ::before for icons — migrating to a new framework requires avoiding this pattern. What’s your migration strategy and how do you measure impact?
How would you architect a CSS system that allows for image overlays without relying on pseudo-elements, while maintaining performance and supporting screen readers?
We’re standardizing our design system across 10+ products, and some teams rely on img::before for UI badges — how do you drive architectural change without breaking existing features or overwhelming teams?
How would you evaluate the long-term maintainability and accessibility tradeoffs of using wrapper <span> elements instead of pseudo-elements on images at scale?
If a major browser changed its behavior to allow pseudo-elements on replaced elements, what ripple effects would that have on our CSS architecture, testing strategy, and third-party component vendors?